<?php
// $Id$

/**
 * Controller_Projects controller
 */
class Controller_Projects extends Controller_Abstract
{
    function actionIndex()
    {
        // 确定查询条件
        $type = strtolower(trim($this->_context->type));
        $key = trim($this->_context->key);

        $conditions = array('is_approbated' => true);

        // 取得当前用户
        $user = $this->_app->currentUser();
        $this->_view['user'] = $user;

        $pagination_args = array();

        // 根据查询类型确定查询条件
        switch ($type)
        {
        case 'cat':
            $conditions['category.slug'] = $key;
            break;
        case 'member':
            $conditions['owner.username'] = $key;

            // 如果是显示当前登录用户的项目，则同时显示未通过审核的项目
            if (!empty($user['username']) && $user['username'] == $key)
            {
                unset($conditions['is_approbated']);
            }
            break;
        default:
            $type = null;
        }

        if ($type)
        {
            $pagination_args['type'] = $type;
            $pagination_args['key']  = $key;
        }

        // 确定排序规则
        $order = strtolower(trim($this->_context->order));
        if ($order)
        {
            // 检查排序规则是否有效
            $order = Q::normalize(strtolower($order), '-');
            if (in_array($order[0], array('downloads_count', 'rating', 'updated')))
            {
                $order_key = $order[0];
                $order_dir = (isset($order[1]) && strtolower($order[1]) == 'desc') ? 'DESC' : 'ASC';
                $pagination_args['order'] = "{$order_key}-{$order_dir}";
                $order = "{$order_key} {$order_dir}";
            }
            else
            {
                $order = null;
            }
        }

        if (!$order)
        {
            $order = 'created DESC';
            $pagination_args['order'] = 'created-DESC';
        }

        // 分页查询
        $page = intval($this->_context->page);
        if ($page < 1) $page = 1;
        $select = Project::find($conditions)->limitPage($page, Q::ini('appini/site/items_pagination'))->order($order);
        $this->_view['pagination'] = $select->getPagination();
        $this->_view['pagination_args'] = $pagination_args;
        $this->_view['projects'] = $select->query();
    }

    /**
     * 显示指定项目的详情
     */
    function actionShow()
    {
        $user = $this->_app->currentUser();
        $this->_view['user'] = $user;

        $name = strtolower(trim($this->_context->name));
        $project = Project::find('[name] = ? AND (is_approbated = ? OR member_id = ?)', $name, true, $user['id'])->query();
        if (!$project->id())
        {
            return $this->_redirect(url('projects/index'));
        }
        $this->_view['project'] = $project;
    }

    /**
     * 创建新项目
     */
    function actionCreate()
    {
        $form = Form_Project::createForm(url('projects/create'));
        $form->_cancel_url = url('projects/index', array(
            'type' => 'member',
            'key' => $this->_app->currentUserObject()->username)
        );

        if ($this->_context->isPOST() && $form->validate($_POST))
        {
            // 如果是 POST 请求，并且提交的表单通过验证，则创建对象
            try
            {
                $project = new Project($form->values());
                $project->owner = $this->_app->currentUserObject();
                $project->save();
                return $this->_redirect(url('projects/edit', array('name' => $project->name)) . '#add_file');
            }
            catch (QValidator_ValidateFailedException $ex)
            {
                // 如果保存时抛出了验证失败异常，则将表单置为无效状态
                $form->invalidate($ex);
            }
        }
        elseif (!$this->_context->isPOST())
        {
            $form->import(new Project());
        }

        $this->_view['form'] = $form;
    }

    /**
     * 编辑已有的项目
     *
     * @param Form_Upload $upload_form
     */
    function actionEdit(Form_Upload $upload_form = null)
    {
        $name = strtolower(trim($this->_context->name));
        // 查询时限定当前用户，可以避免提交非法数据篡改其他用户的项目信息
        $project = Project::find('[name] = ? AND member_id = ?', $name, $this->_app->currentUserObject()->id())->query();
        if (!$project->id())
        {
            return $this->_redirect(url('projects/index'));
        }

        $form = Form_Project::createForm(url('projects/edit', array('name' => $project->name)), 'edit');
        $form->_cancel_url = url('projects/show', array('name' => $project->name));

        if (is_null($upload_form) && $this->_context->isPOST() && $form->validate($_POST))
        {
            // 如果是 POST 操作，并且表单通过验证，则更新已有的对象
            try
            {
                $project->changeProps($form->values());
                $next_action = 'show';
                if ($form['is_pending_delete']->value() && !$project->is_pending_delete)
                {
                    // 申请删除
                    $project->pendingDelete();
                    $next_action = 'pending_delete';
                }
                elseif ($project->is_pending_delete && !$form['is_pending_delete']->value())
                {
                    // 取消删除
                    $project->pendingDelete(false);
                    $next_action = 'cancel_delete';
                }

                $project->save();

                if ($next_action == 'pending_delete')
                {
                    return $this->_redirectMessage(
                        '提示信息',
                        '您的项目删除请求已经提交，管理员审核后将尽快处理。',
                        url('projects/show', array('name' => $project->name)));
                }

                if ($next_action == 'cancel_delete')
                {
                    return $this->_redirectMessage(
                        '提示信息',
                        '您的项目删除请求已经取消。',
                        url('projects/show', array('name' => $project->name)));
                }

                return $this->_redirect(url('projects/show', array('name' => $project->name)));
            }
            catch (QValidator_ValidateFailedException $ex)
            {
                $form->invalidate($ex);
            }
        }
        elseif (!is_null($upload_form) || !$this->_context->isPOST())
        {
            $form->import($project);
            $form['is_pending_delete']->checked = $project->is_pending_delete;
        }

        $this->_view['project'] = $project;
        $this->_view['form'] = $form;
        if (is_null($upload_form))
        {
            $upload_form = Form_Project::createUploadForm(url('projects/upload', array(
                'name' => $project->name))
            );
        }
        $this->_view['upload_form'] = $upload_form;
    }

    function actionUpload()
    {
        $name = strtolower(trim($this->_context->name));
        // 查询时限定当前用户，可以避免提交非法数据篡改其他用户的项目信息
        $project = Project::find('[name] = ? AND member_id = ?', $name, $this->_app->currentUserObject()->id())->query();
        if (!$project->id())
        {
            return $this->_redirect(url('projects/index'));
        }

        $upload_form = Form_Project::createUploadForm(url('projects/upload', array(
            'name' => $project->name))
        );
        if ($upload_form->validate($_POST))
        {
            try
            {
                $file = new ProjectFile();
                $file->project = Project::find('name = ? AND member_id = ?',
                                               $this->_context->name,
                                               $this->_app->currentUserObject()->id())->query();
                $file->summary = $upload_form['summary']->value;
                $file->postfile = $upload_form['postfile']->value;
                $file->save();

                return $this->_redirect(url('projects/edit', array('name' => $file->project->name)) . '#list_files');
            }
            catch (QValidator_ValidateFailedException $ex)
            {
                $upload_form->invalidate($ex);
            }
        }

        // 将请求转发到 actionEdit()，以便重新显示表单
        return $this->_forward('projects/edit', $upload_form);
    }

    /**
     * 下载项目文件
     */
    function actionDownload()
    {
        $name = strtolower(trim($this->_context->name));
        $file = intval($this->_context->file);
        // 如果是用户下载自己项目的文件，则不要求项目已经通过审核
        $user = $this->_app->currentUser();
        if (!empty($user))
        {
            $query = '[id] = ? AND [project.name] = ? AND ([project.member_id] = ? OR [project.is_approbated] = ?)';
            $file = ProjectFile::find($query, $file, $name, $user['id'], true)->query();
        }
        else
        {
            $query = '[id] = ? AND [project.name] = ? AND [project.is_approbated] = ?';
            $file = ProjectFile::find($query, $file, $name, true)->query();
        }

        if ($file->id())
        {
            $file->addDownload(array(
                'remote_addr'     => $this->_context->server('REMOTE_ADDR', ''),
                'http_referer'    => $this->_context->server('HTTP_REFERER', ''),
                'http_user_agent' => $this->_context->server('HTTP_USER_AGENT', ''),
                'user_id'         => empty($user['id']) ? 0 : $user['id'])
            )->save();

            ProjectFile::incrDownloadsCount($file->id());
            Project::incrDownloadsCount($file->project_id);

            $output = new QView_Output($file->filename);
            $output->addFile($file->filepath);
            return $output;
        }

        return $this->_redirect(url('projects/index'));
    }

    /**
     * 删除项目文件
     */
    function actionDeleteFile()
    {
        // 只允许删除自己项目的文件
        $name = strtolower(trim($this->_context->name));
        $file = intval($this->_context->file);
        $user = $this->_app->currentUser();
        if (!empty($user))
        {
            $query = '[id] = ? AND [project.name] = ? AND [project.member_id] = ?';
            ProjectFile::meta()->destroyWhere($query, $file, $name, $user['id']);
        }

        return $this->_redirect(url('projects/edit', array('name' => $name)) . '#list_files');
    }
}


